#coding: utf-8
from .flash import Flash
import time

class NUM480(object):
    CHIP_CORE = 'Cortex-M4'

    PAGE_SIZE = 1024 * 4
    SECT_SIZE = 1024 * 4
    CHIP_SIZE = 0x080000  # 512K

    def __init__(self, jlink):
        super(NUM480, self).__init__()
        
        self.jlink  = jlink

        self.flash = Flash(self.jlink, NUM480_flash_algo)

    def sect_erase(self, addr, size):
        self.flash.Init(0, 0, 1)
        for i in range(0, (size + self.SECT_SIZE - 1)//self.SECT_SIZE):
            self.flash.EraseSector(0x10000000 + addr + self.SECT_SIZE * i)
        self.flash.UnInit(1)

    def chip_write(self, addr, data):
        data = data + [0xFF] * (self.PAGE_SIZE - len(data)%self.PAGE_SIZE)

        self.sect_erase(addr, len(data))

        self.flash.Init(0, 0, 2)
        for i in range(0, len(data)//self.PAGE_SIZE):
            self.flash.ProgramPage(0x10000000 + addr + self.PAGE_SIZE * i, data[self.PAGE_SIZE*i : self.PAGE_SIZE*(i+1)])
        self.flash.UnInit(2)

    def chip_read(self, addr, size, buff):
        data = self.jlink.read_mem(addr, size)

        buff.extend([ord(x) for x in data])


NUM480_flash_algo = {
    'load_address' : 0x20000000,
    'instructions' : [
        0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
        0xBF00B501, 0x1E419800, 0x28009100, 0xBD08D1FA, 0x41F0E92D, 0x460F4606, 0x25644690, 0x49F72059,
        0xF04F6008, 0xF04F0016, 0xF8C14180, 0xF04F0100, 0xF8C10088, 0xF04F0100, 0xF8D04080, 0xF0100100,
        0xD1020F01, 0xE8BD2001, 0x48ED81F0, 0xF0406800, 0xF04F0004, 0xF8C14180, 0x46080200, 0x0204F8D0,
        0x0004F040, 0x0204F8C1, 0x0080F04F, 0xFFC8F7FF, 0x49E548E4, 0xBF006008, 0x680048E4, 0x0F04F010,
        0x48E3D0FA, 0xF0246804, 0xF0440407, 0xF04F0002, 0xF8C14180, 0xF44F0210, 0xF7FF7040, 0x48DDFFB1,
        0xF0406800, 0x49DB0021, 0x46086008, 0xF04069C0, 0x61C80001, 0x68004608, 0x0F01F010, 0x2001D101,
        0x48D4E7C1, 0xF0406800, 0x49D20040, 0x20006008, 0x4601E7B9, 0x48CFBF00, 0xF0106900, 0xD1FA0F01,
        0x680048CC, 0x0021F020, 0x60104ACA, 0x69C04610, 0x0001F020, 0x48C661D0, 0xF0406800, 0xF04F0007,
        0xF8C24280, 0xF04F0210, 0x47700000, 0xBF004601, 0x690048C0, 0x0F01F010, 0x48BED1FA, 0xF0406800,
        0x4ABC0040, 0x20226010, 0xF02160D0, 0x60500003, 0x1F00F5B1, 0x48B8D101, 0x20016090, 0x61104AB5,
        0x8F60F3BF, 0x48B3BF00, 0xF0106900, 0xD1FA0F01, 0x680048B0, 0x0F40F010, 0x48AED007, 0xF0406800,
        0x4AAC0040, 0x20016010, 0x20004770, 0x4601E7FC, 0x48A8BF00, 0xF0106900, 0xD1FA0F01, 0x680048A5,
        0x0040F040, 0x60104AA3, 0x60D02025, 0x60414610, 0x1F00F5B1, 0x48A0D101, 0x20016090, 0x61104A9D,
        0x8F60F3BF, 0x489BBF00, 0xF0106900, 0xD1FA0F01, 0x68004898, 0x0F40F010, 0x4896D007, 0xF0406800,
        0x4A940040, 0x20016010, 0x20004770, 0xB570E7FC, 0x460D4604, 0xE01A2300, 0x0023F834, 0x0C800480,
        0x1AE8D10C, 0xD3092804, 0x0023F854, 0xFFBFF7FF, 0xD0010006, 0xBD704630, 0xE0081D1B, 0x0023F854,
        0xFF84F7FF, 0xD0010006, 0xE7F44630, 0x42AB1C5B, 0x2000D3E2, 0xB570E7EF, 0x460B4604, 0x22004615,
        0xF1034629, 0xF020000F, 0xBF00030F, 0x69004879, 0x0F01F010, 0x4877D1FA, 0xF0406800, 0x4E750040,
        0xF0246030, 0x6070000F, 0x60F02027, 0x1C524610, 0x0020F851, 0x60304E71, 0xF1024610, 0xF8510201,
        0x4E6C0020, 0x0084F8C6, 0xF1024610, 0xF8510201, 0x4E6B0020, 0x46106030, 0x0201F102, 0x0020F851,
        0x0604F106, 0xF04F6030, 0x4E620001, 0xF1A36130, 0xE0290310, 0x4863BF00, 0xF0106800, 0xD1FA0F30,
        0x1C524610, 0x0020F851, 0x60304E5C, 0xF1024610, 0xF8510201, 0x4E570020, 0x0084F8C6, 0x4859BF00,
        0xF0106800, 0xD1FA0FC0, 0x1C524610, 0x0020F851, 0x60304E53, 0xF1024610, 0xF8510201, 0x4E4D0020,
        0x008CF8C6, 0x0310F1A3, 0xD1D32B00, 0x4849BF00, 0xF0106900, 0xD1FA0F01, 0xBD702000, 0x4603B510,
        0xF0201CC8, 0xBF000103, 0x69004842, 0x0F01F010, 0x4840D1FA, 0xF0406800, 0x4C3E0040, 0x20216020,
        0xE01F60E0, 0x0003F023, 0x60604C3A, 0x60A06810, 0x61202001, 0x8F60F3BF, 0x4836BF00, 0xF0106900,
        0xD1FA0F01, 0x68004833, 0x0F40F010, 0x4831D007, 0xF0406800, 0x4C2F0040, 0x20016020, 0x1D1BBD10,
        0x1F091D12, 0xD1DD2900, 0xE7F72000, 0x47F0E92D, 0x460C4605, 0xF04F4616, 0x46C20800, 0x4825BF00,
        0xF0106900, 0xD1FA0F01, 0x68004822, 0x0040F040, 0x60084920, 0xF0201CE0, 0xE0450403, 0x0DC005E8,
        0xF5B4D10C, 0xD3097F00, 0x7700F44F, 0x0208EB06, 0x46284639, 0xFF2FF7FF, 0xE0164682, 0x0DC005E8,
        0x2C10D10B, 0xF024D309, 0xEB06070F, 0x46390208, 0xF7FF4628, 0x4682FF20, 0x4627E007, 0x0208EB06,
        0x46284639, 0xFF8AF7FF, 0x443D4682, 0x1BE444B8, 0x0F00F1BA, 0x2001D018, 0x87F0E8BD, 0x40000100,
        0x40000200, 0x0008421E, 0x40000240, 0x40000250, 0x40000210, 0x4000C000, 0x0055AA03, 0x4000C080,
        0x4000C088, 0x4000C0C0, 0xD1B72C00, 0xE8BD2000, 0xB51087F0, 0xF0231CCB, 0xBF000103, 0x691B4B2D,
        0x0F01F013, 0x4B2BD1FA, 0xF043681B, 0x4C290340, 0x23006023, 0xE02460E3, 0x0303F020, 0x60634C25,
        0x60A32300, 0x61232301, 0x8F60F3BF, 0x4B21BF00, 0xF013691B, 0xD1FA0F01, 0x681B4B1E, 0x0F40F013,
        0x4B1CD006, 0xF043681B, 0x4C1A0340, 0xBD106023, 0x689B4B18, 0x42A36814, 0xE7F8D000, 0x1D121D00,
        0x29001F09, 0xBF00D1D8, 0xB510E7F1, 0x48114603, 0xF0106E00, 0xD00C0F02, 0x6503480E, 0x65826541,
        0x4C0C2001, 0xBF0065E0, 0x6E00480A, 0x0F01F010, 0x4808D1FA, 0xF0106E00, 0xD1010F04, 0xBD102002,
        0x6E004804, 0x0F02F010, 0x2001D001, 0x2000E7F7, 0x0000E7F5, 0x4000C000, 0x00000000
    ],

    'pc_Init'            : 0x20000031,
    'pc_UnInit'          : 0x200000F3,
    'pc_EraseSector'     : 0x2000012D,
    'pc_ProgramPage'     : 0x2000038D,
    'pc_Verify'          : 0x20000453,
    'pc_EraseChip'       : 0x12000001F,
    'pc_BlankCheck'      : 0x12000001F,
    'pc_Read'            : 0x12000001F,
    
    'static_base'        : 0x20000800,
    'begin_data'         : 0x20000C00,
    'begin_stack'        : 0x20002000,

    'analyzer_supported' : False,

    # Relative region addresses and sizes
    'ro_start'           : 0x00000000,
    'ro_size'            : 0x000004F8,
    'rw_start'           : 0x000004F8,
    'rw_size'            : 0x00000004,
    'zi_start'           : 0x000004FC,
    'zi_size'            : 0x00000000,

    # Flash information
    'flash_start'        : 0x00000000,
    'flash_size'         : 0x00080000,
    'flash_page_size'    : 0x00001000,
    'sector_sizes': (
        (0x00000, 0x01000),
    )
}
